﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Spectrum
{
    /// <summary>
    /// 反应谱参数
    /// </summary>
    public class SpectParam
    {
        /// <summary>
        /// 影响系数
        /// </summary>
        public float Afa { set; get; }

        /// <summary>
        /// 速度
        /// </summary>
        public float Velocity { set; get; }

        /// <summary>
        /// 位移
        /// </summary>
        public float Disp { set; get; }

        /// <summary>
        /// 周期值
        /// </summary>
        public float Period { set; get; }

        /// <summary>
        /// 获得相应最大值
        /// </summary>
        /// <param name="response"></param>
        public void SetSpectrum(ResponseSet response, bool isPeseudo)
        {
            this.Afa = Math.Max(this.Afa, response.GetAfaMax(isPeseudo));
            this.Velocity = Math.Max(this.Velocity, response.GetVelocityMax(isPeseudo));
            this.Disp = Math.Max(this.Disp, response.Umax);
        }

        /// <summary>
        /// 空的构造函数
        /// </summary>
        public SpectParam()
        {

        }

        /// <summary>
        /// 构造反应谱值
        /// </summary>
        /// <param name="period"></param>
        /// <param name="isPeseudo"></param>
        /// <param name="response"></param>
        public SpectParam(float period, bool isPeseudo, ResponseSet response)
        {
            //获得响应最大值
            this.SetSpectrum(response, isPeseudo);
            //获得周期
            this.Period = period;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="period"></param>
        /// <param name="afa"></param>
        public SpectParam(float period, float afa, float velocity, float disp)
        {
            this.Period = period;
            this.Afa = afa;
            this.Velocity = velocity;
            this.Disp = disp;
        }
    }

    /// <summary>
    /// 反应谱分析结果
    /// </summary>
    public class SpectSet
    {
        #region Variables

        /// <summary>
        /// 反应谱分析结果
        /// </summary>
        private List<SpectParam> Results { set; get; }

        /// <summary>
        /// 外部激励
        /// </summary>
        private List<AccelParam> Accel { set; get; }

        /// <summary>
        /// 外部激励Y
        /// </summary>
        private List<AccelParam> AccelY { set; get; }

        /// <summary>
        /// 周期长度
        /// </summary>
        private float PeriodLength { set; get; }

        /// <summary>
        /// 周期增量
        /// </summary>
        private float DeltaPeriod { set; get; }

        #endregion

        /// <summary>
        /// 获得分析结果
        /// </summary>
        /// <param name="paramList"></param>
        /// <param name="dampingRatio"></param>
        /// <param name="isPeseudo"></param>
        /// <returns></returns>
        public List<SpectParam> GetResults(List<float> paramList, float dampingRatio, bool isPeseudo)
        {
            //确定分析步数目
            int stepNumber = (int)(this.PeriodLength / this.DeltaPeriod) + 1;
            //初始化
            this.Results = new List<Spectrum.SpectParam>(stepNumber - 1);
            //遍历每个分析步
            for (int step = 1; step < stepNumber; step++)
            {
                //确定周期
                float period = this.DeltaPeriod * step;
                //构造
                var response = new ResponseSet(this.Accel, paramList, period, dampingRatio);
                //获得反应谱值
                var spect = new SpectParam(period, isPeseudo, response);
                //是否存在Y向时程
                if (this.AccelY.Count != 0)
                {
                    //构造Y向时程响应
                    var responseY = new ResponseSet(this.AccelY, paramList, period, dampingRatio);
                    //获得SRSS响应
                    var responseSRSS = responseY.GetSRSSResponse(response);
                    //获得影响系数最大值
                    spect.SetSpectrum(responseY, isPeseudo);
                    spect.SetSpectrum(responseSRSS, isPeseudo);
                }
                //获得最大影响系数
                this.Results.Add(spect);
            }
            //返回分析结果
            return this.Results;
        }

        /// <summary>
        /// 空的构造函数
        /// </summary>
        public SpectSet()
        {
            this.Results = new List<Spectrum.SpectParam>();
            this.Accel = new List<Spectrum.AccelParam>();
            this.AccelY = new List<Spectrum.AccelParam>();
        }

        /// <summary>
        /// 主构造函数
        /// </summary>
        /// <param name="accel"></param>
        /// <param name="periodLength"></param>
        /// <param name="deltaPeriod"></param>
        public SpectSet(List<AccelParam> accel, List<AccelParam> accelY, float periodLength, float deltaPeriod)
        {
            this.Accel = accel;
            this.AccelY = accelY;
            this.PeriodLength = periodLength;
            this.DeltaPeriod = deltaPeriod;
        }
    }
}
